procedure condence(); // e - array of edges, m - edges count, c - component of current vertex
 
var
        i, tt, x, y, cur, v, j : longint;
        g, gr : array[0..20010] of array of longint;
        w : array[0..20010] of boolean;
        o, cc : array[0..20010] of longint;
 
        procedure dfs1(v : longint);
 
        var
                i, tt, tto : longint;
 
        begin
                w[v] := true;
                tt := length(g[v]) - 1;
                for i := 0 to tt do begin
                        tto := g[v][i];
                        if not w[tto] then dfs1(tto);
                end;
                inc(o[0]);
                o[o[0]] := v;
        end;
 
        procedure dfs2(v : longint);
 
        var
                i, tt, tto : longint;
 
        begin
                w[v] := true;
                inc(cc[0]);
                cc[cc[0]] := v;
                tt := length(gr[v]) - 1;
                for i := 0 to tt do begin
                        tto := gr[v][i];
                        if not w[tto] then dfs2(tto);
                end;
        end;
 
begin
        for i := 1 to m do begin
                x := e[i].a;
                y := e[i].b;
                tt := length(g[x]);
                setlength(g[x], tt + 1);
                g[x][tt] := y;
                tt := length(gr[y]);
                setlength(gr[y], tt + 1);
                gr[y][tt] := x;
        end;
        fillchar(w, sizeof(w), 0);
        o[0] := 0;
        for i := 1 to n do
                if not w[i] then dfs1(i);
        fillchar(w, sizeof(w), 0);
        cur := 0;
        for i := 1 to n do begin
                v := o[n - i + 1];
                if not w[v] then begin
                        cc[0] := 0;
                        dfs2(v);
                        inc(cur);
                        for j := 1 to cc[0] do
                                c[cc[j]] := cur;
                end;
        end;
end;